﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering;
using UnityEngine;

public partial class MyRender:BaseThread
{
    private Camera _cam;
    private CullingResults _cullResults;
    private bool _useDynamicBatch;
    private bool _useGI;

    private Lighting _lighting = new Lighting();
    private Shadows _shadows = new Shadows();

    public MyRender(bool dB, bool gI, ShadowSettings ss):base("Render Camera")
    {
        _useDynamicBatch = dB;
        _useGI = gI;
        _shadowSettings = ss;
    }

    RenderTexture _shadowMap;
    private DrawingSettings _drawSetting;
    private FilteringSettings _filiterSetting;
    private SortingSettings _sortingSetting;
    private ShadowSettings _shadowSettings;
    
    public void Rendering(ScriptableRenderContext context, Camera cam)
    {
        _context = context;
        _cam = cam;

        if(!_cam)
        {
            return;
        }
        PrepareBuffer();
        PrepareForSceneView();
        
        if (!Cull(_shadowSettings.maxDistance))
        {
            return;
        }
        PrepareShadowAndLight();
        Setup();
        DrawUnsupportShaders();
        DrawVisiableObjects();
        DrawGizmos();
        Submit();

        CleanUp();

    }

    private void Setup()
    {
        _context.SetupCameraProperties(_cam);
        CameraClearFlags flags = _cam.clearFlags;
        _cmd.ClearRenderTarget(flags <= CameraClearFlags.Depth,
            flags == CameraClearFlags.Color,
            flags == CameraClearFlags.Color ? _cam.backgroundColor.linear:Color.clear);
        BeginSample();
          
    }
    private void DrawVisiableObjects()
    {

        _sortingSetting = new SortingSettings(_cam);
        _drawSetting = new DrawingSettings(unlitShaderTagId, _sortingSetting)
        {
            enableDynamicBatching = _useDynamicBatch,
            enableInstancing = _useGI,
            perObjectData = PerObjectData.LightIndices
        };
        _drawSetting.SetShaderPassName(1, litShaderTagId);
        DrawOpaqueObjs();
        _context.DrawSkybox(_cam);
        DrawTransObjs();
    }
    private void Submit()
    {
        EndSample();
        _context.Submit();
    }

   
    private bool Cull(float maxShadowDistance)
    {
        ScriptableCullingParameters _cullParameters;
        if (_cam.TryGetCullingParameters(out _cullParameters))
        {
            _cullParameters.shadowDistance = Mathf.Min(maxShadowDistance, _cam.farClipPlane);
            _cullResults = _context.Cull(ref _cullParameters);
            return true;
        }
        return false;
    }


    private void DrawOpaqueObjs()
    {
        _sortingSetting.criteria = SortingCriteria.CommonOpaque;
        _drawSetting.sortingSettings = _sortingSetting;
        _filiterSetting= new FilteringSettings(RenderQueueRange.opaque);
        _context.DrawRenderers(_cullResults, ref _drawSetting, ref _filiterSetting);
    }

    private void DrawTransObjs()
    {
        _sortingSetting.criteria = SortingCriteria.CommonTransparent;
        _drawSetting.sortingSettings = _sortingSetting;
        _filiterSetting.renderQueueRange = RenderQueueRange.transparent;
        _context.DrawRenderers(_cullResults, ref _drawSetting, ref _filiterSetting);
    }
    

    private void PrepareShadowAndLight()
    {

        _lighting.Setup(_context, _cullResults, _shadowSettings);
    }

    private void CleanUp()
    {
        _shadows.CleanUp();
    }
}
